package com.projectframe.base.utils;

public class ByteUtils
{
    // =================================================
    // byte[] 16进制字符串 互转
    // =================================================
    /**
     * byte[] --> 16进制字符串
     * 
     * @param b
     * @return String
     */
    public static String bytes2ToHexString(byte[] b)
    {
        StringBuffer ret = new StringBuffer();

        for (int i = 0; i < b.length; i++)
        {
            String hex = Integer.toHexString(b[i] & 0xFF);

            if (hex.length() == 1)
            {
                hex = '0' + hex;
            }

            ret.append(hex.toUpperCase());
        }

        return ret.toString();
    }

    /**
     * 16进制字符串 --> byte[]
     * 
     * @param hexStr
     * @return byte[]
     */
    public static byte[] hexStringToBytes2(String hexStr)
    {
        byte[] b = new byte[hexStr.length() / 2];
        char[] cx = new char[2];

        int index = 0;

        for (int i = 0; i < hexStr.length(); i += 2, index++)
        {
            cx[0] = hexStr.charAt(i);
            cx[1] = hexStr.charAt(i + 1);
            String hex = String.valueOf(cx);
            int value = Integer.parseInt(hex, 16);

            b[index] = (byte) (value & 0xFF);
        }

        return b;
    }

    // =================================================
    // int byte[] 互转 (16进制)(4字节)
    // =================================================
    /**
     * int --> byte[] (16进制)(4字节)
     * 
     * @param num
     * @return byte[]
     */
    public static byte[] intToByteHex(int num)
    {
        byte[] bTemp = new byte[4];

        for (int i = 0; i < 4; i++)
        {
            bTemp[i] = (byte) ((num >> (i * 8)) & 0xff);
        }

        return bTemp;
    }

    /**
     * byte[] --> int (16进制)(4字节)
     * 
     * @param c
     * @return int
     */
    public static int byteToIntHex(byte[] c)
    {
        if (c.length == 4)
        {
            return (toInt(c[3]) << 24) + (toInt(c[2]) << 16)
                    + (toInt(c[1]) << 8) + toInt(c[0]);
        }

        return 0;
    }
    
    /**
     * byte[] --> int (16进制)(4字节)
     * 
     * @param c
     * @return int
     */
    public static long byteToLongHex(byte[] c)
    {
        if (c.length == 4)
        {
            long initValue = 0L;
            initValue += (toInt(c[3]) << 24);
            initValue += (toInt(c[2]) << 16);
            initValue += (toInt(c[1]) << 8);
            initValue += toInt(c[0]);
            
            return initValue;
        }

        return 0;
    }

    // =================================================
    // int byte[] 互转 (10进制)(4字节)
    // =================================================

    /**
     * int --> byte[] (10进制)(4字节)
     * 
     * @param num
     * @return byte[]
     */
    public static byte[] intToByte(int num)
    {
        byte[] b = new byte[4];

        for (int i = 0; i < 4; i++)
        {
            b[i] = (byte) (num >>> (24 - i * 8));
        }

        return b;
    }

    /**
     * byte[] --> int (16进制)(4字节)
     * 
     * @param byteValue
     * @return int
     */
    public static int byteToInt(byte[] byteValue)
    {
        if (byteValue.length != 4)
            return 0;

        int intValue = 0;

        try
        {
            intValue = toInt(byteValue[0]);
            intValue = (intValue << 8) + toInt(byteValue[1]);
            intValue = (intValue << 8) + toInt(byteValue[2]);
            intValue = (intValue << 8) + toInt(byteValue[3]);
        }
        catch (Exception e)
        {}

        return intValue;
    }
    
    /**
     * byte[] --> long (16进制)(4字节)
     * 
     * @param byteValue
     * @return int
     */
    public static long byteToLong(byte[] byteValue)
    {
        if (byteValue.length != 4)
            return 0;

        long intValue = 0;

        try
        {
            intValue = toInt(byteValue[0]);
            intValue = (intValue << 8) + toInt(byteValue[1]);
            intValue = (intValue << 8) + toInt(byteValue[2]);
            intValue = (intValue << 8) + toInt(byteValue[3]);
        }
        catch (Exception e)
        {}

        return intValue;
    }

    private static int toInt(byte b)
    {
        if (b >= 0)
            return (int) b;
        else
            return (int) (b + 256);
    }

    // =================================================
    // short byte[] 互转 (16进制)(2字节)
    // =================================================
    /**
     * short byte[] 互转 (16进制)(2字节)
     * 
     * @param num
     * @return byte[]
     */
    public static byte[] shortToByteHex(int num)
    {
        byte[] bTemp = new byte[2];

        for (int i = 0; i < 2; i++)
        {
            bTemp[i] = (byte) ((num >> (i * 8)) & 0xff);
        }

        return bTemp;
    }

    /**
     * byte[] short 互转 (16进制)(2字节)
     * 
     * @param c
     * @return int
     */
    public static int byteToShortHex(byte[] c)
    {
        if (c.length == 2)
        {
            return (toInt(c[1]) << 8) + toInt(c[0]);
        }

        return 0;
    }

    // =================================================
    // short byte[] 互转 (10进制)(2字节)
    // =================================================
    /**
     * short byte[] 互转 (10进制)(2字节)
     * 
     * @param num
     * @return byte[]
     */
    public static byte[] shortToByte(int num)
    {
        byte[] b = new byte[2];

        for (int i = 0; i < 2; i++)
        {
            b[i] = (byte) (num >>> (8 - i * 8));
        }

        return b;
    }

    /**
     * byte[] short 互转 (10进制)(2字节)
     * 
     * @param byteValue
     * @return int
     */
    public static int byteToShort(byte[] byteValue)
    {
        if (byteValue.length != 2)
            return 0;

        int intValue = 0;

        try
        {
            intValue = toInt(byteValue[0]);
            intValue = (intValue << 8) + toInt(byteValue[1]);
        }
        catch (Exception e)
        {}

        return intValue;
    }

    // =================================================
    // Unicode UTF-8 互转
    // =================================================

    private static final int MASKBITS   = 0x3F;
    private static final int MASKBYTE   = 0x80;
    private static final int MASK2BYTES = 0xC0;
    private static final int MASK3BYTES = 0xE0;

    /**
     * @功能: 将UTF-8编码转成UNICODE（UTF-16LE）（UTF-16BE）编码
     * @参数: byte[] b 源字节数组
     * @返回值: byte[] b 转为UNICODE编码后的数组
     */
    public static byte[] UTF8_TO_UNICODE(byte[] b)
    {
        int i = 0;
        int j = 0;
        byte[] unicodeByte = new byte[b.length * 2];

        while (i < b.length)
        {
            byte[] bUnicode = new byte[2];
            bUnicode[0] = bUnicode[1] = 0;
            int nUnicode = 0;
            if ((b[i] & MASK3BYTES) == MASK3BYTES)
            {
                nUnicode = ((b[i] & 0x0F) << 12) | ((b[i + 1] & MASKBITS) << 6)
                        | (b[i + 2] & MASKBITS);
                i += 3;
            }
            // 110xxxxx 10xxxxxx
            else if ((b[i] & MASK2BYTES) == MASK2BYTES)
            {
                nUnicode = ((b[i] & 0x1F) << 6) | (b[i + 1] & MASKBITS);
                i += 2;
            }
            // 0xxxxxxx
            else if (b[i] < MASKBYTE)
            {
                nUnicode = b[i];
                i += 1;
            }

            unicodeByte[j++] = (byte) (nUnicode & 0xFF);
            unicodeByte[j++] = (byte) ((nUnicode >> 8) & 0xFF);
        }

        b = new byte[j];
        System.arraycopy(unicodeByte, 0, b, 0, j);
        return b;
    }

    /**
     * @功能: 将UNICODE（UTF-16LE）（UTF-16BE）编码转成UTF-8编码
     * @参数: byte[] b 源字节数组
     * @返回值: byte[] b 转为UTF-8编码后的数组
     */
    public static byte[] UNICODE_TO_UTF8(byte[] b)
    {
        int i = 0;
        int j = 0;
        byte[] utf8Byte = new byte[b.length * 2];

        while (i < b.length)
        {
            byte[] bUTF = new byte[1];
            int nCode = (b[i] & 0xFF) | ((b[i + 1] & 0xFF) << 8);

            if (nCode < 0x80)
            {
                bUTF = new byte[1];
                bUTF[0] = (byte) nCode;
            }
            // 110xxxxx 10xxxxxx
            else if (nCode < 0x800)
            {
                bUTF = new byte[2];
                bUTF[0] = (byte) (MASK2BYTES | nCode >> 6);
                bUTF[1] = (byte) (MASKBYTE | nCode & MASKBITS);
            }
            // 1110xxxx 10xxxxxx 10xxxxxx
            else if (nCode < 0x10000)
            {
                bUTF = new byte[3];
                bUTF[0] = (byte) (MASK3BYTES | nCode >> 12);
                bUTF[1] = (byte) (MASKBYTE | nCode >> 6 & MASKBITS);
                bUTF[2] = (byte) (MASKBYTE | nCode & MASKBITS);
            }

            for (int k = 0; k < bUTF.length; k++)
            {
                utf8Byte[j++] = bUTF[k];
            }

            i += 2;
        }

        b = new byte[j];
        System.arraycopy(utf8Byte, 0, b, 0, j);
        return b;
    }

    public String bin2hexstr(byte[] src, int start, int len)
    {
        char[] hex = new char[2];

        StringBuffer strBuffer = new StringBuffer(len * 2);

        int abyte;

        for (int i = start; i < start + len; i++)
        {
            abyte = src[i] < 0 ? (256 + src[i]) : src[i];

            hex[0] = HEX[abyte / 16];
            hex[1] = HEX[abyte % 16];

            strBuffer.append(hex);
        }

        return strBuffer.toString();
    }

    public final char[] HEX = { '0', '1', '2', '3', '4', '5', '6', '7', '8',
            '9', 'A', 'B', 'C', 'D', 'E', 'F' };

    public static void main(String[] args)
    {
        // byte[] a = ByteUtils.shortToByte(2324);
        // int b = ByteUtils.byteToShort(a);

        // System.out.println();

        // double a = Math.abs(1.1);
        // System.out.println(a);
        //String ss = String.valueOf( Integer.parseInt("555", 16) );
        //System.out.println(ss);
        
        byte [] b = hexStringToBytes2("0b");
        String aa = bytes2ToHexString(b);
        
        
        System.out.println(aa);
        System.out.println(Integer.parseInt(aa, 16));
    }
}
